#include "PwmS5Controller.h"
#include "PwmOut.h"
#include "SW1248.h"
#include "CmdLine.h"

#include "DataStorage.h"
#include "log.h"

PwmS5Controller::PwmS5Controller(I2CSlave& i2c_slave,DataStorage& dataStorage,PwmS5& pwmS5):_i2c_slave(i2c_slave),_dataStorage(dataStorage),_pwmS5(pwmS5)
{
    _isr_update = false;
}

PwmS5Controller::~PwmS5Controller()
{
    
}
void PwmS5Controller::begin()
{
    module_general_reg_t& module_general_reg = DataStorage::module_reg().module_general_reg;

    module_status_number_reg_t& module_status_number_reg = module_general_reg.module_status_number_reg;

    module_general_info_t& info = module_general_reg.module_general_info[module_status_number_reg.value];

    this->apply_setup_update(module_general_reg,info);
}
void PwmS5Controller::schedule()
{
    if(_isr_update){
        return;
    }

    if(!_i2c_slave.read(_reg_data_read)){
        return;
    }

    this->update();
    
}

void PwmS5Controller::update_pwm_fixed_freq(PwmOut& pwmout,uint8_t freq_num,float duty_cycle)
{
        switch(freq_num)
        {
            case 0x00:pwmout.set_frequency(FREQ_31HZ,duty_cycle);break;
            case 0x01:pwmout.set_frequency(FREQ_125HZ,duty_cycle);break;
            case 0x02:pwmout.set_frequency(FREQ_500HZ,duty_cycle);break;
            case 0x03:pwmout.set_frequency(FREQ_4KHZ,duty_cycle);break;
            case 0x04:pwmout.set_frequency(FREQ_32KHZ,duty_cycle);break;
            default:
            {
                log::debug("set error mss:freq_num:%d,duty_cycle:%f\r\n",freq_num,duty_cycle);
            }
            break;
        }
}

void PwmS5Controller::apply_setup_update(module_general_reg_t& module_general_reg,module_general_info_t& info)
{
    module_control_reg_t& module_control_reg = module_general_reg.module_control_reg;
    module_control_reg.value =  _reg_data_read.memory.data[1];
        
    //更新设置R
    if(info.pin_used_reg.pin.red == PinState::Open){ 
        //RED
        if(info.pin_output_mode_reg.pin.red == 0)//开关模式
        {
            _pwmS5.dio_set().red().write(!module_general_reg.module_pin_level_reg.red);
        }
        else if(info.freq_mode_select_status_reg.sm==0)//PWM模式-选择频率
        {
            this->update_pwm_fixed_freq(_pwmS5.pwm_set().red(),info.freq_mode_select_status_reg.value&0x07,info.pwm_duty_cycle_reg.red_pin.value*1.0/100);
        }else//PWM模式-自定义频率
        {
            _pwmS5.pwm_set().red().set_frequency(info.pwm_custom_freq_reg.red_pin.value,info.pwm_duty_cycle_reg.red_pin.value*1.0/100);
        }
    }
    //GREEN
    if(info.pin_used_reg.pin.green == PinState::Open){ 
        if(info.pin_output_mode_reg.pin.green == 0){
            _pwmS5.dio_set().green().write(!module_general_reg.module_pin_level_reg.green);
        }
        else if(info.freq_mode_select_status_reg.sm==0)//PWM模式-选择频率
        {
            this->update_pwm_fixed_freq(_pwmS5.pwm_set().green(),info.freq_mode_select_status_reg.value&0x07,info.pwm_duty_cycle_reg.green_pin.value*1.0/100);
        }else//PWM模式-自定义频率
        {
            _pwmS5.pwm_set().green().set_frequency(info.pwm_custom_freq_reg.green_pin.value,info.pwm_duty_cycle_reg.green_pin.value*1.0/100);
        }
    }
    //BLUE
    if(info.pin_used_reg.pin.blue == PinState::Open){
        if(info.pin_output_mode_reg.pin.blue == 0){
                _pwmS5.dio_set().blue().write(!module_general_reg.module_pin_level_reg.blue);
        }
        else if(info.freq_mode_select_status_reg.sm==0)//PWM模式-选择频率
        {
            this->update_pwm_fixed_freq(_pwmS5.pwm_set().blue(),info.freq_mode_select_status_reg.value&0x07,info.pwm_duty_cycle_reg.blue_pin.value*1.0/100);
        }else//PWM模式-自定义频率
        {
            _pwmS5.pwm_set().blue().set_frequency(info.pwm_custom_freq_reg.blue_pin.value,info.pwm_duty_cycle_reg.blue_pin.value*1.0/100);
        }
    }
    //WHITE
    if(info.pin_used_reg.pin.white == PinState::Open){
        if(info.pin_output_mode_reg.pin.white == 0){
            _pwmS5.dio_set().white().write(!module_general_reg.module_pin_level_reg.white);
        }
        else if(info.freq_mode_select_status_reg.sm==0)//PWM模式-选择频率
        {
            this->update_pwm_fixed_freq(_pwmS5.pwm_set().white(),info.freq_mode_select_status_reg.value&0x07,info.pwm_duty_cycle_reg.white_pin.value*1.0/100);
        }else//PWM模式-自定义频率
        {
            //不支持-关闭IO
            //_pwmS5.dio_set().white().write(1);
        }
    }
    //YELLOW
    if(info.pin_used_reg.pin.yellow == PinState::Open){
        if(info.pin_output_mode_reg.pin.yellow == 0){
            _pwmS5.dio_set().yellow().write(!module_general_reg.module_pin_level_reg.yellow);
        }
        else if(info.freq_mode_select_status_reg.sm==0)//PWM模式-选择频率
        {
            this->update_pwm_fixed_freq(_pwmS5.pwm_set().yellow(),info.freq_mode_select_status_reg.value&0x07,info.pwm_duty_cycle_reg.yellow_pin.value*1.0/100);
        }else//PWM模式-自定义频率
        {
            //不支持-关闭IO
            //_pwmS5.dio_set().yellow().write(1);
        }
    }
}
void PwmS5Controller::update()
{
    //SN寄存器0,1,2,3
    module_general_reg_t& module_general_reg = DataStorage::module_reg().module_general_reg;

    module_status_number_reg_t& module_status_number_reg = module_general_reg.module_status_number_reg;

    module_general_info_t& info = module_general_reg.module_general_info[module_status_number_reg.value];

    // log::debug("mem:%x:%x:%x-%x:%x:%x\r\n",
    //             _reg_data_read.memory.data[0],
    //             _reg_data_read.memory.data[1],
    //             _reg_data_read.memory.data[2],
    //             _reg_data_read.memory.data[3],
    //             _reg_data_read.memory.data[4],
    //             _reg_data_read.memory.data[5]);
    switch(_reg_data_read.memory.data[0]){
        case 0x40://主机数据-保留
        break;
        case 0x41://中断-保留
        break;
        case 0x42://更新设置
        {
            this->apply_setup_update(module_general_reg,info);
        }
        break;
        case 0x43://更新占空比
        {
            //此寄存器禁用
        }
        break;
        case 0x44://状态编号 (S)tatus (N)umber
        {
            //切换状态编号
            module_status_number_reg.value = _reg_data_read.memory.data[1];
            module_general_reg.module_actived_status_reg.value =0;
            switch (module_status_number_reg.value)
            {
            case 0:module_general_reg.module_actived_status_reg.as0 = 1; break;
            case 1:module_general_reg.module_actived_status_reg.as1 = 1; break;
            case 2:module_general_reg.module_actived_status_reg.as2 = 1; break;
            case 3:module_general_reg.module_actived_status_reg.as3 = 1; break;
            default:break;
            }
           
           log::debug("0x44->SN:%d:%d\r\n",module_status_number_reg.value,module_general_reg.module_actived_status_reg.value);
        }
        break;
        case 0x45://已启用的状态 (A)ctived (S)tatus 0x03[0x45]
        {
            //禁止写: (read only)
        }
        break;
        case 0x46://保留
        break;
        case 0x47:
        {
            //设置引脚电平
            module_general_reg.module_pin_level_reg.value = _reg_data_read.memory.data[1];
            //RED
            if(info.pin_output_mode_reg.pin.red == 0)//开关模式
            {
                _pwmS5.dio_set().red().write(!module_general_reg.module_pin_level_reg.red);
            }
            // else if(info.freq_mode_select_status_reg.sm==0)//PWM模式-选择频率
            // {
            //     this->update_pwm_fixed_freq(_pwmS5.pwm_set().red(),info.freq_mode_select_status_reg.value&0x07,info.pwm_duty_cycle_reg.red_pin.value*1.0/100);
            // }else//自定义频率
            // {
            //     _pwmS5.pwm_set().red().set_frequency(info.pwm_custom_freq_reg.red_pin.value,info.pwm_duty_cycle_reg.red_pin.value*1.0/100);
            // }

            //GREEN
            if(info.pin_output_mode_reg.pin.green == 0){
                    _pwmS5.dio_set().green().write(!module_general_reg.module_pin_level_reg.green);
            }
            // else if(info.freq_mode_select_status_reg.sm==0)//PWM模式-选择频率
            // {
            //     this->update_pwm_fixed_freq(_pwmS5.pwm_set().green(),info.freq_mode_select_status_reg.value&0x07,info.pwm_duty_cycle_reg.green_pin.value*1.0/100);
            // }else//自定义频率
            // {
            //     _pwmS5.pwm_set().green().set_frequency(info.pwm_custom_freq_reg.green_pin.value,info.pwm_duty_cycle_reg.green_pin.value*1.0/100);
            // }

            //BLUE
            if(info.pin_output_mode_reg.pin.blue == 0){
                    _pwmS5.dio_set().blue().write(!module_general_reg.module_pin_level_reg.blue);
            }
            // else if(info.freq_mode_select_status_reg.sm==0)//PWM模式-选择频率
            // {
            //     this->update_pwm_fixed_freq(_pwmS5.pwm_set().blue(),info.freq_mode_select_status_reg.value&0x07,info.pwm_duty_cycle_reg.blue_pin.value*1.0/100);
            // }else//自定义频率
            // {
            //     _pwmS5.pwm_set().blue().set_frequency(info.pwm_custom_freq_reg.blue_pin.value,info.pwm_duty_cycle_reg.blue_pin.value*1.0/100);
            // }

            //WHITE
            if(info.pin_output_mode_reg.pin.white == 0){
                _pwmS5.dio_set().white().write(!module_general_reg.module_pin_level_reg.white);
            }
            // else if(info.freq_mode_select_status_reg.sm==0)//PWM模式-选择频率
            // {
            //     this->update_pwm_fixed_freq(_pwmS5.pwm_set().white(),info.freq_mode_select_status_reg.value&0x07,info.pwm_duty_cycle_reg.white_pin.value*1.0/100);
            // }else//自定义频率
            // {
            //     //不支持
            // }

            //YELLOW
            if(info.pin_output_mode_reg.pin.yellow == 0){
                _pwmS5.dio_set().yellow().write(!module_general_reg.module_pin_level_reg.yellow);
            }
            // else if(info.freq_mode_select_status_reg.sm==0)//PWM模式-选择频率
            // {
            //     this->update_pwm_fixed_freq(_pwmS5.pwm_set().yellow(),info.freq_mode_select_status_reg.value&0x07,info.pwm_duty_cycle_reg.yellow_pin.value*1.0/100);
            // }else//自定义频率
            // {
            //     //不支持
            // }
            log::debug("0x47->write:%d:%d\r\n",module_general_reg.module_pin_level_reg.value,info.pin_output_mode_reg.value);
        }
        break;
        case 0x48:
        {   
            //选择频率模式下的频率编号, 共有4种, 编号为 0-3, 如果为自定义模式, 这个值无效
            //用于设定该状态的模式, 选择频率模式还是自定义频率模式
            // 0 选择频率模式.(默认)
            // 1 自定义频率模式.
            module_freq_mode_select_status_reg_t reg;
            reg.value = _reg_data_read.memory.data[1];
            if(reg.sm==1){
                info.freq_mode_select_status_reg.sm = 1;
            }else{
                info.freq_mode_select_status_reg.value = _reg_data_read.memory.data[1];
            }
            this->apply_setup_update(module_general_reg,info);
            log::debug("0x48:%d\r\n",reg.value);
        }
        break;
        case 0x49:
        {
            //0: 功能关闭
            //1: 功能使能
            info.pin_used_reg.value = _reg_data_read.memory.data[1];
            if(info.pin_used_reg.pin.red==0){
                _pwmS5.dio_set().red().write(1);//写1关闭
            }
            if(info.pin_used_reg.pin.green==0){
                _pwmS5.dio_set().red().write(1);//写1关闭
            }
            if(info.pin_used_reg.pin.blue==0){
                _pwmS5.dio_set().red().write(1);//写1关闭
            }
            if(info.pin_used_reg.pin.white==0){
                _pwmS5.dio_set().red().write(1);//写1关闭
            }
            if(info.pin_used_reg.pin.yellow==0){
                _pwmS5.dio_set().red().write(1);//写1关闭
            }
        }
        break;
        case 0x4A:
        {
            // 0: 开关模式, (默认)输出高低电平. PWM 无法全部关断.
            // 1: PWM模式
            info.pin_output_mode_reg.value = _reg_data_read.memory.data[1];
            this->apply_setup_update(module_general_reg,info);
            log::debug("4a->write:%d\r\n",info.pin_output_mode_reg.value);
        }
        break;
        case 0x4B:
        {   
            // R 引脚占空比
            info.pwm_duty_cycle_reg.red_pin.value = _reg_data_read.memory.data[1];
            if( (info.pin_used_reg.pin.red != PinState::Close) && (info.pin_output_mode_reg.pin.red != PinOutMode::SW)){
                if(info.pwm_duty_cycle_reg.red_pin.value>100){
                    info.pwm_duty_cycle_reg.red_pin.value = 100;
                }
                _pwmS5.pwm_set().red().write(info.pwm_duty_cycle_reg.red_pin.value*1.0/100);
                log::debug("4B->write:%f\r\n",info.pwm_duty_cycle_reg.red_pin.value*1.0/100);
            }
        }
        break;
        case 0x4C:
        {
            // G 引脚占空比
            info.pwm_duty_cycle_reg.green_pin.value = _reg_data_read.memory.data[1];
            if( (info.pin_used_reg.pin.green != PinState::Close) && (info.pin_output_mode_reg.pin.green != PinOutMode::SW)){
                if(info.pwm_duty_cycle_reg.green_pin.value>100){
                    info.pwm_duty_cycle_reg.green_pin.value = 100;
                }
                _pwmS5.pwm_set().green().write(info.pwm_duty_cycle_reg.green_pin.value*1.0/100);
            }
        }
        break;
        case 0x4D:
        {
            // B 引脚占空比
            info.pwm_duty_cycle_reg.blue_pin.value = _reg_data_read.memory.data[1];
            if( (info.pin_used_reg.pin.blue != PinState::Close)  && (info.pin_output_mode_reg.pin.blue != PinOutMode::SW)){
                if(info.pwm_duty_cycle_reg.blue_pin.value>100){
                    info.pwm_duty_cycle_reg.blue_pin.value = 100;
                }
                _pwmS5.pwm_set().blue().write(info.pwm_duty_cycle_reg.blue_pin.value*1.0/100);
            }
        }
        break;
        case 0x4E:
        {
            // W 引脚占空比
            info.pwm_duty_cycle_reg.white_pin.value = _reg_data_read.memory.data[1];
            if( (info.pin_used_reg.pin.white != PinState::Close)  && (info.pin_output_mode_reg.pin.white != PinOutMode::SW)){
                if(info.pwm_duty_cycle_reg.white_pin.value>100){
                    info.pwm_duty_cycle_reg.white_pin.value = 100;
                }
                _pwmS5.pwm_set().white().write(info.pwm_duty_cycle_reg.white_pin.value*1.0/100);
            }
        }
        break;
        case 0x4F:
        {
            // Y 引脚占空比
            info.pwm_duty_cycle_reg.yellow_pin.value = _reg_data_read.memory.data[1];
            if( (info.pin_used_reg.pin.yellow != PinState::Close)  && (info.pin_output_mode_reg.pin.yellow != PinOutMode::SW)){
                if(info.pwm_duty_cycle_reg.yellow_pin.value>100){
                    info.pwm_duty_cycle_reg.yellow_pin.value = 100;
                }
                _pwmS5.pwm_set().yellow().write(info.pwm_duty_cycle_reg.yellow_pin.value*1.0/100);
            }
        }
        break;
        case 0x50:
        case 0x51:
        case 0x52:
        case 0x53:
        {
            // R 频率 high
            info.pwm_custom_freq_reg.red_pin.data[0] = _reg_data_read.memory.data[1];
            info.pwm_custom_freq_reg.red_pin.data[1] = _reg_data_read.memory.data[2];
            info.pwm_custom_freq_reg.red_pin.data[2] = _reg_data_read.memory.data[3];
            info.pwm_custom_freq_reg.red_pin.data[3] = _reg_data_read.memory.data[4];
            _pwmS5.pwm_set().red().set_frequency(info.pwm_custom_freq_reg.red_pin.value,info.pwm_duty_cycle_reg.red_pin.value*1.0/100);
        }
        break;
        case 0x54:
        case 0x55:
        case 0x56:
        case 0x57:
        {
            // G 频率 high
            info.pwm_custom_freq_reg.green_pin.data[0]  = _reg_data_read.memory.data[1];
            info.pwm_custom_freq_reg.green_pin.data[1] = _reg_data_read.memory.data[2];
            info.pwm_custom_freq_reg.green_pin.data[2] = _reg_data_read.memory.data[3];
            info.pwm_custom_freq_reg.green_pin.data[3] = _reg_data_read.memory.data[4];
            _pwmS5.pwm_set().green().set_frequency(info.pwm_custom_freq_reg.green_pin.value,info.pwm_duty_cycle_reg.green_pin.value*1.0/100);
        }
        break;
        case 0x58:
        case 0x59:
        case 0x5A:
        case 0x5B:
        {
            // B 频率 high
            info.pwm_custom_freq_reg.blue_pin.data[0]  = _reg_data_read.memory.data[1];
            info.pwm_custom_freq_reg.blue_pin.data[1] = _reg_data_read.memory.data[2];
            info.pwm_custom_freq_reg.blue_pin.data[2] = _reg_data_read.memory.data[3];
            info.pwm_custom_freq_reg.blue_pin.data[3] = _reg_data_read.memory.data[4];
            _pwmS5.pwm_set().blue().set_frequency(info.pwm_custom_freq_reg.blue_pin.value,info.pwm_duty_cycle_reg.blue_pin.value*1.0/100);
        }
        break;
        default:break;
    }
}
void PwmS5Controller::cleanup()
{

}
